import de.javasoft.plaf.synthetica.SyntheticaBlueMoonLookAndFeel;
import java.awt.FileDialog;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileFilter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.util.StringTokenizer;
import java.util.Vector;
import javax.swing.JFileChooser;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import neuralj.datasets.Pattern;
import neuralj.datasets.PatternSet;
import neuralj.networks.feedforward.FeedForwardNeuralNetwork;
import neuralj.networks.feedforward.Neuron;
import neuralj.networks.feedforward.activation.ActivationFunctionLinear;
import neuralj.networks.feedforward.activation.ActivationFunctionSigmoid;
import neuralj.networks.feedforward.activation.IActivationFunction;
import neuralj.networks.feedforward.learning.FeedForwardNetworkLearningAlgorithm;
import neuralj.networks.feedforward.learning.bprop.BackPropagation;
import neuralj.networks.feedforward.learning.genetic.GeneticAlgorithm;
import neuralj.networks.feedforward.learning.rprop.ResilientBackPropagation;
import neuralj.testers.ConsoleTester;
import neuralj.testers.StringTester;
import neuralj.watchers.ConsoleWatcher;
/*
 * NewJFrame.java
 *
 * Created on 29 de Julho de 2006, 3:05
 */

/**
 *
 * @author  Administrador
 */
public class NewJFrame extends javax.swing.JFrame {
    
    public static FeedForwardNeuralNetwork network = null;
    public static int activation = 0;
    public static FeedForwardNetworkLearningAlgorithm algorithm = null;
    
    /** Creates new form NewJFrame */
    public NewJFrame() {
        initComponents();
        setInterfaceStateAwaitingInput();
        comboLearning.removeAllItems();
        comboLearning.addItem(new String("BackPropagation"));
        comboLearning.addItem(new String("Resilient BackPropagation"));
        comboLearning.addItem(new String("Genetic Algorithm"));
        comboActivation.removeAllItems();
        comboActivation.addItem(new String("Sigmoid"));
        comboActivation.addItem(new String("Linear"));
        spinnerInput.setModel(new SpinnerNumberModel(2.0,1.0,1000.0,1.0));
        spinnerOutput.setModel(new SpinnerNumberModel(1.0,1.0,1000.0,1.0));
        spinnerHidden1.setModel(new SpinnerNumberModel(2.0,1.0,1000.0,1.0));
        spinnerHidden2.setModel(new SpinnerNumberModel(0.0,0.0,1000.0,1.0));
        spinnerHidden3.setModel(new SpinnerNumberModel(0.0,0.0,1000.0,1.0));
        spinnerEpochs.setModel(new SpinnerNumberModel(10000.0,0.0,1000000000.0,1.0));
        btnStart.setEnabled(false);
        btnSaveWeights.setEnabled(false);
        txtPrediction.setEnabled(false);
        btnGuess.setEnabled(false);
    }
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
    private void initComponents() {
        groupNetworkTopology = new javax.swing.JPanel();
        labelInput = new javax.swing.JLabel();
        labelOutput = new javax.swing.JLabel();
        labelHidden1 = new javax.swing.JLabel();
        labelHidden2 = new javax.swing.JLabel();
        labelHidden3 = new javax.swing.JLabel();
        spinnerInput = new javax.swing.JSpinner();
        spinnerHidden1 = new javax.swing.JSpinner();
        spinnerHidden2 = new javax.swing.JSpinner();
        spinnerHidden3 = new javax.swing.JSpinner();
        spinnerOutput = new javax.swing.JSpinner();
        labelNetworkTopology = new javax.swing.JLabel();
        groupTrainingParameters = new javax.swing.JPanel();
        labelTrainingFile = new javax.swing.JLabel();
        txtTrainingFile = new javax.swing.JTextField();
        btnOpenTrainingFile = new javax.swing.JButton();
        labelTrainingParameters = new javax.swing.JLabel();
        labelTrainingLog = new javax.swing.JLabel();
        labelValidationLog = new javax.swing.JLabel();
        txtTrainingLogFile = new javax.swing.JTextField();
        txtValidationLogFile = new javax.swing.JTextField();
        btnOpenTrainingLogFile = new javax.swing.JButton();
        btnOpenValidationLogFile = new javax.swing.JButton();
        groupLearningParameters = new javax.swing.JPanel();
        labelEpochs = new javax.swing.JLabel();
        labelMSE = new javax.swing.JLabel();
        labelLearningRate = new javax.swing.JLabel();
        spinnerEpochs = new javax.swing.JSpinner();
        txtMSE = new javax.swing.JTextField();
        txtLearningRate = new javax.swing.JTextField();
        txtMomentum = new javax.swing.JTextField();
        labelMomentum = new javax.swing.JLabel();
        comboLearning = new javax.swing.JComboBox();
        comboActivation = new javax.swing.JComboBox();
        labelLearningAlgorithm = new javax.swing.JLabel();
        labelActivationFunction = new javax.swing.JLabel();
        labelLearningParameters = new javax.swing.JLabel();
        groupExecution = new javax.swing.JPanel();
        labelCurrentEpoch = new javax.swing.JLabel();
        labelCurrentMSE = new javax.swing.JLabel();
        labelCurrentStatus = new javax.swing.JLabel();
        btnStart = new javax.swing.JButton();
        btnLoadWeights = new javax.swing.JButton();
        btnSaveWeights = new javax.swing.JButton();
        labelExecution = new javax.swing.JLabel();
        groupPrediction = new javax.swing.JPanel();
        labelPrediction = new javax.swing.JLabel();
        jScrollPane1 = new javax.swing.JScrollPane();
        txtPrediction = new javax.swing.JTextArea();
        btnGuess = new javax.swing.JButton();
        btnGuessFile = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("BackPropagation GUI");
        setName("MainForm");
        setResizable(false);
        groupNetworkTopology.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        groupNetworkTopology.setName("f");
        labelInput.setText("Input Neurons:");

        labelOutput.setText("Output Neurons:");

        labelHidden1.setText("Hidden Neurons (1): ");

        labelHidden2.setText("Hidden Neurons (2):");

        labelHidden3.setText("Hidden Neurons (3):");

        spinnerInput.setName("spinnerInputNeurons");
        spinnerInput.setVerifyInputWhenFocusTarget(false);
        spinnerInput.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                spinnerInputStateChanged(evt);
            }
        });

        spinnerHidden1.setName("spinnerHiddenNeuronsOne");
        spinnerHidden1.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                spinnerHidden1StateChanged(evt);
            }
        });

        spinnerHidden2.setName("spinnerHiddenNeuronsTwo");
        spinnerHidden2.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                spinnerHidden2StateChanged(evt);
            }
        });

        spinnerHidden3.setName("spinnerHiddenNeuronsThree");
        spinnerHidden3.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                spinnerHidden3StateChanged(evt);
            }
        });

        spinnerOutput.setName("spinnerOutputNeurons");
        spinnerOutput.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                spinnerOutputStateChanged(evt);
            }
        });

        labelNetworkTopology.setFont(new java.awt.Font("Tahoma", 1, 11));
        labelNetworkTopology.setText("Network Topology");

        org.jdesktop.layout.GroupLayout groupNetworkTopologyLayout = new org.jdesktop.layout.GroupLayout(groupNetworkTopology);
        groupNetworkTopology.setLayout(groupNetworkTopologyLayout);
        groupNetworkTopologyLayout.setHorizontalGroup(
            groupNetworkTopologyLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(groupNetworkTopologyLayout.createSequentialGroup()
                .add(groupNetworkTopologyLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(groupNetworkTopologyLayout.createSequentialGroup()
                        .addContainerGap()
                        .add(groupNetworkTopologyLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                            .add(labelHidden2)
                            .add(labelHidden1)
                            .add(labelInput)
                            .add(labelOutput)
                            .add(labelHidden3))
                        .add(18, 18, 18)
                        .add(groupNetworkTopologyLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                            .add(spinnerHidden1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 141, Short.MAX_VALUE)
                            .add(spinnerHidden2, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 141, Short.MAX_VALUE)
                            .add(spinnerHidden3, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 141, Short.MAX_VALUE)
                            .add(spinnerOutput, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 141, Short.MAX_VALUE)
                            .add(spinnerInput, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 141, Short.MAX_VALUE)))
                    .add(labelNetworkTopology))
                .addContainerGap())
        );
        groupNetworkTopologyLayout.setVerticalGroup(
            groupNetworkTopologyLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(groupNetworkTopologyLayout.createSequentialGroup()
                .add(labelNetworkTopology)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(groupNetworkTopologyLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(labelInput)
                    .add(spinnerInput, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(groupNetworkTopologyLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(labelHidden1)
                    .add(spinnerHidden1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(groupNetworkTopologyLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(labelHidden2)
                    .add(spinnerHidden2, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(groupNetworkTopologyLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(labelHidden3)
                    .add(spinnerHidden3, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(groupNetworkTopologyLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(labelOutput)
                    .add(spinnerOutput, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addContainerGap())
        );

        groupTrainingParameters.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        labelTrainingFile.setText("Training file:");

        txtTrainingFile.setEnabled(false);
        txtTrainingFile.setName("txtTrainingFile");

        btnOpenTrainingFile.setText("...");
        btnOpenTrainingFile.setName("btnOpenTrainingFile");
        btnOpenTrainingFile.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                btnOpenTrainingFileMouseClicked(evt);
            }
        });

        labelTrainingParameters.setFont(new java.awt.Font("Tahoma", 1, 11));
        labelTrainingParameters.setText("Training parameters");

        labelTrainingLog.setText("Training log:");

        labelValidationLog.setText("Validation log:");

        txtTrainingLogFile.setEnabled(false);

        txtValidationLogFile.setEnabled(false);

        btnOpenTrainingLogFile.setText("...");
        btnOpenTrainingLogFile.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                btnOpenTrainingLogFileMouseClicked(evt);
            }
        });

        btnOpenValidationLogFile.setText("...");
        btnOpenValidationLogFile.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                btnOpenValidationLogFileMouseClicked(evt);
            }
        });

        org.jdesktop.layout.GroupLayout groupTrainingParametersLayout = new org.jdesktop.layout.GroupLayout(groupTrainingParameters);
        groupTrainingParameters.setLayout(groupTrainingParametersLayout);
        groupTrainingParametersLayout.setHorizontalGroup(
            groupTrainingParametersLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(groupTrainingParametersLayout.createSequentialGroup()
                .add(groupTrainingParametersLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(groupTrainingParametersLayout.createSequentialGroup()
                        .addContainerGap()
                        .add(groupTrainingParametersLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                            .add(labelValidationLog)
                            .add(labelTrainingLog))
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(groupTrainingParametersLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                            .add(txtValidationLogFile, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 97, Short.MAX_VALUE)
                            .add(txtTrainingLogFile, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 97, Short.MAX_VALUE)))
                    .add(labelTrainingParameters)
                    .add(groupTrainingParametersLayout.createSequentialGroup()
                        .addContainerGap()
                        .add(labelTrainingFile)
                        .add(12, 12, 12)
                        .add(txtTrainingFile, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 97, Short.MAX_VALUE)))
                .add(groupTrainingParametersLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(groupTrainingParametersLayout.createSequentialGroup()
                        .add(12, 12, 12)
                        .add(groupTrainingParametersLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING, false)
                            .add(org.jdesktop.layout.GroupLayout.LEADING, btnOpenTrainingLogFile, 0, 0, Short.MAX_VALUE)
                            .add(org.jdesktop.layout.GroupLayout.LEADING, btnOpenTrainingFile, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 47, Short.MAX_VALUE)))
                    .add(org.jdesktop.layout.GroupLayout.TRAILING, groupTrainingParametersLayout.createSequentialGroup()
                        .add(12, 12, 12)
                        .add(btnOpenValidationLogFile, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 47, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap())
        );
        groupTrainingParametersLayout.setVerticalGroup(
            groupTrainingParametersLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(groupTrainingParametersLayout.createSequentialGroup()
                .add(labelTrainingParameters)
                .add(12, 12, 12)
                .add(groupTrainingParametersLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(labelTrainingFile)
                    .add(btnOpenTrainingFile)
                    .add(txtTrainingFile, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .add(35, 35, 35)
                .add(groupTrainingParametersLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(labelTrainingLog)
                    .add(txtTrainingLogFile, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .add(btnOpenTrainingLogFile))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(groupTrainingParametersLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(labelValidationLog)
                    .add(txtValidationLogFile, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .add(btnOpenValidationLogFile))
                .addContainerGap(19, Short.MAX_VALUE))
        );

        groupLearningParameters.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        labelEpochs.setText("Epochs:");

        labelMSE.setText("Mean Squared Error:");

        labelLearningRate.setText("Learning Rate:");

        spinnerEpochs.setName("spinnerEpochs");

        txtMSE.setText("0.001");
        txtMSE.setName("txtMSE");
        txtMSE.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                txtMSEPropertyChange(evt);
            }
        });
        txtMSE.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyTyped(java.awt.event.KeyEvent evt) {
                txtMSEKeyTyped(evt);
            }
        });
        txtMSE.addVetoableChangeListener(new java.beans.VetoableChangeListener() {
            public void vetoableChange(java.beans.PropertyChangeEvent evt)throws java.beans.PropertyVetoException {
                txtMSEVetoableChange(evt);
            }
        });

        txtLearningRate.setText("1.0");
        txtLearningRate.setName("txtLearningRate");

        txtMomentum.setText("0.1");
        txtMomentum.setName("txtMomentum");

        labelMomentum.setText("Momentum:");

        comboLearning.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
        comboLearning.setName("comboLearningAlgorithm");
        comboLearning.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                comboLearningItemStateChanged(evt);
            }
        });

        comboActivation.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
        comboActivation.setName("comboActivationFunction");
        comboActivation.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                comboActivationItemStateChanged(evt);
            }
        });

        labelLearningAlgorithm.setText("Learning Algorithm:");

        labelActivationFunction.setText("Activation Function:");

        labelLearningParameters.setFont(new java.awt.Font("Tahoma", 1, 11));
        labelLearningParameters.setText("Learning parameters");

        org.jdesktop.layout.GroupLayout groupLearningParametersLayout = new org.jdesktop.layout.GroupLayout(groupLearningParameters);
        groupLearningParameters.setLayout(groupLearningParametersLayout);
        groupLearningParametersLayout.setHorizontalGroup(
            groupLearningParametersLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(groupLearningParametersLayout.createSequentialGroup()
                .add(groupLearningParametersLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(labelLearningParameters)
                    .add(groupLearningParametersLayout.createSequentialGroup()
                        .addContainerGap()
                        .add(groupLearningParametersLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                            .add(labelLearningAlgorithm)
                            .add(labelMomentum)
                            .add(labelLearningRate)
                            .add(labelActivationFunction)
                            .add(labelMSE)
                            .add(labelEpochs))
                        .add(10, 10, 10)
                        .add(groupLearningParametersLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                            .add(txtMSE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 129, Short.MAX_VALUE)
                            .add(txtLearningRate, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 129, Short.MAX_VALUE)
                            .add(comboActivation, 0, 129, Short.MAX_VALUE)
                            .add(txtMomentum, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 129, Short.MAX_VALUE)
                            .add(comboLearning, 0, 129, Short.MAX_VALUE)
                            .add(spinnerEpochs, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 129, Short.MAX_VALUE))))
                .addContainerGap())
        );
        groupLearningParametersLayout.setVerticalGroup(
            groupLearningParametersLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(groupLearningParametersLayout.createSequentialGroup()
                .add(labelLearningParameters)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .add(groupLearningParametersLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(labelEpochs)
                    .add(spinnerEpochs, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(groupLearningParametersLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(labelMSE)
                    .add(txtMSE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(groupLearningParametersLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(labelLearningRate)
                    .add(txtLearningRate, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(groupLearningParametersLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(labelMomentum)
                    .add(txtMomentum, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(groupLearningParametersLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(labelLearningAlgorithm)
                    .add(comboLearning, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(groupLearningParametersLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(labelActivationFunction)
                    .add(comboActivation, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addContainerGap())
        );

        groupExecution.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        labelCurrentEpoch.setText("Number of Epochs: 0");

        labelCurrentMSE.setText("Best MSE: 0.00");

        labelCurrentStatus.setText("Status: Awaiting input...");

        btnStart.setText("Start");
        btnStart.setName("btnStart");
        btnStart.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                btnStartMouseClicked(evt);
            }
        });

        btnLoadWeights.setText("Load Weights");
        btnLoadWeights.setName("btnLoadWeights");
        btnLoadWeights.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                btnLoadWeightsMouseClicked(evt);
            }
        });

        btnSaveWeights.setText("Save Weights");
        btnSaveWeights.setName("btnSaveWeights");
        btnSaveWeights.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                btnSaveWeightsMouseClicked(evt);
            }
        });

        labelExecution.setFont(new java.awt.Font("Tahoma", 1, 11));
        labelExecution.setText("Execution");

        org.jdesktop.layout.GroupLayout groupExecutionLayout = new org.jdesktop.layout.GroupLayout(groupExecution);
        groupExecution.setLayout(groupExecutionLayout);
        groupExecutionLayout.setHorizontalGroup(
            groupExecutionLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(groupExecutionLayout.createSequentialGroup()
                .add(groupExecutionLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(labelExecution)
                    .add(groupExecutionLayout.createSequentialGroup()
                        .addContainerGap()
                        .add(btnStart)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(groupExecutionLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                            .add(btnSaveWeights, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 162, Short.MAX_VALUE)
                            .add(btnLoadWeights, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 162, Short.MAX_VALUE)))
                    .add(groupExecutionLayout.createSequentialGroup()
                        .addContainerGap()
                        .add(labelCurrentStatus, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 227, Short.MAX_VALUE))
                    .add(org.jdesktop.layout.GroupLayout.TRAILING, groupExecutionLayout.createSequentialGroup()
                        .addContainerGap()
                        .add(labelCurrentMSE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 227, Short.MAX_VALUE))
                    .add(groupExecutionLayout.createSequentialGroup()
                        .addContainerGap()
                        .add(labelCurrentEpoch, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 227, Short.MAX_VALUE)))
                .addContainerGap())
        );
        groupExecutionLayout.setVerticalGroup(
            groupExecutionLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(groupExecutionLayout.createSequentialGroup()
                .add(labelExecution)
                .add(21, 21, 21)
                .add(labelCurrentEpoch)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(labelCurrentMSE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(labelCurrentStatus)
                .add(28, 28, 28)
                .add(groupExecutionLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false)
                    .add(groupExecutionLayout.createSequentialGroup()
                        .add(btnLoadWeights)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(btnSaveWeights))
                    .add(btnStart, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap())
        );

        groupPrediction.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        labelPrediction.setFont(new java.awt.Font("Tahoma", 1, 11));
        labelPrediction.setText("Prediction");

        txtPrediction.setColumns(20);
        txtPrediction.setRows(5);
        jScrollPane1.setViewportView(txtPrediction);

        btnGuess.setText("Guess (training)");
        btnGuess.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                btnGuessMouseClicked(evt);
            }
        });

        btnGuessFile.setText("Guess (file)");
        btnGuessFile.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                btnGuessFileMouseClicked(evt);
            }
        });

        org.jdesktop.layout.GroupLayout groupPredictionLayout = new org.jdesktop.layout.GroupLayout(groupPrediction);
        groupPrediction.setLayout(groupPredictionLayout);
        groupPredictionLayout.setHorizontalGroup(
            groupPredictionLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(groupPredictionLayout.createSequentialGroup()
                .add(groupPredictionLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(groupPredictionLayout.createSequentialGroup()
                        .add(labelPrediction)
                        .add(177, 177, 177)
                        .add(btnGuessFile, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 143, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .add(btnGuess, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 143, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                    .add(groupPredictionLayout.createSequentialGroup()
                        .addContainerGap()
                        .add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 516, Short.MAX_VALUE)))
                .addContainerGap())
        );
        groupPredictionLayout.setVerticalGroup(
            groupPredictionLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(groupPredictionLayout.createSequentialGroup()
                .add(groupPredictionLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(labelPrediction)
                    .add(groupPredictionLayout.createSequentialGroup()
                        .addContainerGap()
                        .add(groupPredictionLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                            .add(btnGuess)
                            .add(btnGuessFile, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 22, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .add(jScrollPane1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 78, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
                    .add(org.jdesktop.layout.GroupLayout.LEADING, groupPrediction, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .add(layout.createSequentialGroup()
                        .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
                            .add(groupNetworkTopology, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .add(groupLearningParameters, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false)
                            .add(groupExecution, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .add(groupTrainingParameters, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .addContainerGap()
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(groupTrainingParameters, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .add(groupNetworkTopology, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(groupExecution, 0, 189, Short.MAX_VALUE)
                    .add(groupLearningParameters, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(groupPrediction, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );
        pack();
    }// </editor-fold>//GEN-END:initComponents
    
    private void btnGuessFileMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_btnGuessFileMouseClicked
        JFileChooser fc = new JFileChooser();
        fc.setFileFilter(new CSVFilter());
        int returnVal = fc.showOpenDialog(this);
        
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            File file = fc.getSelectedFile();
            String path = file.getAbsolutePath();
            PatternSet pattern_set = new PatternSet();
            Pattern.split_token = ",";
            int input = (int)Double.parseDouble(spinnerInput.getValue().toString());
            pattern_set.loadPatterns(path, input);
            StringTester tester = new StringTester(this.network);
            txtPrediction.setText(tester.test(pattern_set));
        }
    }//GEN-LAST:event_btnGuessFileMouseClicked
    
    private void spinnerOutputStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spinnerOutputStateChanged
        buildNeuralNetwork();
    }//GEN-LAST:event_spinnerOutputStateChanged
    
    private void spinnerHidden3StateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spinnerHidden3StateChanged
        buildNeuralNetwork();
    }//GEN-LAST:event_spinnerHidden3StateChanged
    
    private void spinnerHidden2StateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spinnerHidden2StateChanged
        buildNeuralNetwork();
    }//GEN-LAST:event_spinnerHidden2StateChanged
    
    private void spinnerHidden1StateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spinnerHidden1StateChanged
        buildNeuralNetwork();
    }//GEN-LAST:event_spinnerHidden1StateChanged
    
    private void spinnerInputStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spinnerInputStateChanged
        buildNeuralNetwork();
    }//GEN-LAST:event_spinnerInputStateChanged
    
    private void comboActivationItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_comboActivationItemStateChanged
        buildNeuralNetwork();
    }//GEN-LAST:event_comboActivationItemStateChanged
    
    private void btnLoadWeightsMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_btnLoadWeightsMouseClicked
        JFileChooser fc = new JFileChooser();
        fc.setFileFilter(new CSVFilter());
        int returnVal = fc.showOpenDialog(this);
        
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            File file = fc.getSelectedFile();
            String path = file.getAbsolutePath();
            loadWeights(path);
        }
    }//GEN-LAST:event_btnLoadWeightsMouseClicked
    
    private void btnSaveWeightsMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_btnSaveWeightsMouseClicked
        JFileChooser fc = new JFileChooser();
        fc.setFileFilter(new CSVFilter());
        int returnVal = fc.showOpenDialog(this);
        
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            File file = fc.getSelectedFile();
            String path = file.getAbsolutePath();
            String extension = path.substring(path.length()-4, path.length());
            if (extension != null)
                if (!extension.toLowerCase().equals(".csv"))
                    path += ".csv";
            saveWeights(path);
        }
    }//GEN-LAST:event_btnSaveWeightsMouseClicked
    
    private void comboLearningItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_comboLearningItemStateChanged
        switch(comboLearning.getSelectedIndex()) {
            case 0:
                txtLearningRate.setEnabled(true);
                txtMomentum.setEnabled(true);
                break;
            case 1:
                txtLearningRate.setEnabled(false);
                txtMomentum.setEnabled(false);
                break;
            case 2:
                txtLearningRate.setEnabled(false);
                txtMomentum.setEnabled(false);
                break;
        }
    }//GEN-LAST:event_comboLearningItemStateChanged
    
    private void buildNeuralNetwork() {
        int input = (int)Double.parseDouble(spinnerInput.getValue().toString());
        int [] hidden = new int[1];
        hidden[0] = 1;
        if((int)Double.parseDouble(spinnerHidden1.getValue().toString()) > 0) {
            hidden = new int[1];
            hidden[0] = (int)Double.parseDouble(spinnerHidden1.getValue().toString());
            if((int)Double.parseDouble(spinnerHidden2.getValue().toString()) > 0) {
                hidden = new int[2];
                hidden[0] = (int)Double.parseDouble(spinnerHidden1.getValue().toString());
                hidden[1] = (int)Double.parseDouble(spinnerHidden2.getValue().toString());
                
                if((int)Double.parseDouble(spinnerHidden3.getValue().toString()) > 0) {
                    hidden = new int[3];
                    hidden[0] = (int)Double.parseDouble(spinnerHidden1.getValue().toString());
                    hidden[1] = (int)Double.parseDouble(spinnerHidden2.getValue().toString());
                    hidden[2] = (int)Double.parseDouble(spinnerHidden3.getValue().toString());
                }
            }
        }
        int output = (int)Double.parseDouble(spinnerOutput.getValue().toString());
        
        network = new FeedForwardNeuralNetwork(input,hidden,output);
        
        switch(comboActivation.getSelectedIndex()) {
            case 0:
                network.setActivationFunction(new ActivationFunctionSigmoid());
                activation = 0;
                break;
            case 1:
                network.setActivationFunction(new ActivationFunctionLinear());
                activation = 1;
                break;
        }
    }
    
    private void btnOpenValidationLogFileMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_btnOpenValidationLogFileMouseClicked
        JFileChooser fc = new JFileChooser();
        fc.setFileFilter(new CSVFilter());
        int returnVal = fc.showOpenDialog(this);
        
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            File file = fc.getSelectedFile();
            String path = file.getAbsolutePath();
            String extension = path.substring(path.length()-4, path.length());
            if (extension != null)
                if (!extension.toLowerCase().equals(".csv"))
                    path += ".csv";
            txtValidationLogFile.setText(path);
        }
    }//GEN-LAST:event_btnOpenValidationLogFileMouseClicked
    
    private void btnOpenTrainingLogFileMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_btnOpenTrainingLogFileMouseClicked
        JFileChooser fc = new JFileChooser();
        fc.setFileFilter(new CSVFilter());
        int returnVal = fc.showOpenDialog(this);
        
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            File file = fc.getSelectedFile();
            String path = file.getAbsolutePath();
            String extension = path.substring(path.length()-4, path.length());
            if (extension != null)
                if (!extension.toLowerCase().equals(".csv"))
                    path += ".csv";
            txtTrainingLogFile.setText(path);
        }
    }//GEN-LAST:event_btnOpenTrainingLogFileMouseClicked
    
    private void btnGuessMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_btnGuessMouseClicked
        if(!txtTrainingFile.getText().equals("")) {
            PatternSet pattern_set = new PatternSet();
            Pattern.split_token = ",";
            int input = (int)Double.parseDouble(spinnerInput.getValue().toString());
            pattern_set.loadPatterns(txtTrainingFile.getText(), input);
            StringTester tester = new StringTester(this.network);
            txtPrediction.setText(tester.test(pattern_set));
        }
    }//GEN-LAST:event_btnGuessMouseClicked
    
    private void txtMSEKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_txtMSEKeyTyped
                                    }//GEN-LAST:event_txtMSEKeyTyped
    
    private void txtMSEPropertyChange(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_txtMSEPropertyChange
                                    }//GEN-LAST:event_txtMSEPropertyChange
    
    private void txtMSEVetoableChange(java.beans.PropertyChangeEvent evt)throws java.beans.PropertyVetoException {//GEN-FIRST:event_txtMSEVetoableChange
                                    }//GEN-LAST:event_txtMSEVetoableChange
    
    private void btnOpenTrainingFileMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_btnOpenTrainingFileMouseClicked
        JFileChooser fc = new JFileChooser();
        fc.setFileFilter(new CSVFilter());
        int returnVal = fc.showOpenDialog(this);
        
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            File file = fc.getSelectedFile();
            txtTrainingFile.setText(file.getAbsolutePath());
            btnStart.setEnabled(true);
        }
    }//GEN-LAST:event_btnOpenTrainingFileMouseClicked
    
    private void btnStartMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_btnStartMouseClicked
        
        if(btnStart.getText().equals("Start")) {
            PatternSet training_set = new PatternSet();
            Pattern.split_token = ",";
            int input = (int)Double.parseDouble(spinnerInput.getValue().toString());
            training_set.loadPatterns(txtTrainingFile.getText(), input);
            training_set.generateSets();
            
            if(network == null)
                buildNeuralNetwork();
            
            switch(comboLearning.getSelectedIndex()) {
                case 0:
                    algorithm = new BackPropagation(network);
                    ((BackPropagation)algorithm).learning_rate = Double.parseDouble(txtLearningRate.getText());
                    ((BackPropagation)algorithm).momentum_rate = Double.parseDouble(txtMomentum.getText());
                    break;
                case 1:
                    algorithm = new ResilientBackPropagation(network);
                    algorithm.start();
                    break;
                case 2:
                    algorithm = new GeneticAlgorithm(network);
                    break;
            }
            
            algorithm.pattern_set = training_set;
            algorithm.is_running = true;
            algorithm.watcher = new InterfaceWatcher(algorithm,this,txtTrainingLogFile.getText(),txtValidationLogFile.getText());
            algorithm.learning_strategy = FeedForwardNetworkLearningAlgorithm.LearningStrategy.Generalization;
            algorithm.desired_error = Double.parseDouble(txtMSE.getText());
            algorithm.maximum_epochs = (int) Double.parseDouble(spinnerEpochs.getValue().toString());
            algorithm.start();
        } else {
            algorithm.is_running = false;
            setInterfaceStateAwaitingInput();
        }
    }//GEN-LAST:event_btnStartMouseClicked
    
    public void setCurrentEpoch(int epoch) {
        labelCurrentEpoch.setText("Current epoch: " + epoch);
    }
    
    public void setCurrentMSE(double mse) {
        labelCurrentMSE.setText("Best MSE: " + mse);
    }
    
    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    UIManager.setLookAndFeel(new SyntheticaBlueMoonLookAndFeel());
                } catch (Exception e) {
                    e.printStackTrace();
                }
                new NewJFrame().setVisible(true);
            }
        });
    }
    
    public void setInterfaceStateTraining() {
        SwingUtilities.invokeLater(new Runnable(){
            public void run(){
                spinnerEpochs.setEnabled(false);
                txtMSE.setEnabled(false);
                txtLearningRate.setEnabled(false);
                txtMomentum.setEnabled(false);
                txtLearningRate.setEnabled(false);
                btnStart.setText("Stop");
                btnLoadWeights.setEnabled(false);
                btnSaveWeights.setEnabled(false);
                btnOpenTrainingFile.setEnabled(false);
                btnStart.setEnabled(true);
                comboLearning.setEnabled(false);
                spinnerHidden1.setEnabled(false);
                spinnerHidden2.setEnabled(false);
                spinnerHidden3.setEnabled(false);
                spinnerInput.setEnabled(false);
                spinnerOutput.setEnabled(false);
                comboActivation.setEnabled(false);
                btnGuess.setEnabled(false);
                txtPrediction.setEnabled(true);
                labelCurrentStatus.setText("Status: Training...");
            }});
    }
    
    public void setInterfaceStateAwaitingInput() {
        SwingUtilities.invokeLater(new Runnable(){
            public void run(){
                spinnerEpochs.setEnabled(true);
                txtMSE.setEnabled(true);
                txtLearningRate.setEnabled(true);
                txtMomentum.setEnabled(true);
                txtLearningRate.setEnabled(true);
                btnStart.setText("Start");
                btnLoadWeights.setEnabled(true);
                btnSaveWeights.setEnabled(true);
                btnOpenTrainingFile.setEnabled(true);
                btnStart.setEnabled(true);
                comboLearning.setEnabled(true);
                spinnerHidden1.setEnabled(true);
                spinnerHidden2.setEnabled(true);
                spinnerHidden3.setEnabled(true);
                spinnerInput.setEnabled(true);
                spinnerOutput.setEnabled(true);
                comboActivation.setEnabled(true);
                btnGuess.setEnabled(true);
                labelCurrentStatus.setText("Status: Awaiting input...");
            }});
    }
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnGuess;
    private javax.swing.JButton btnGuessFile;
    private javax.swing.JButton btnLoadWeights;
    private javax.swing.JButton btnOpenTrainingFile;
    private javax.swing.JButton btnOpenTrainingLogFile;
    private javax.swing.JButton btnOpenValidationLogFile;
    private javax.swing.JButton btnSaveWeights;
    private javax.swing.JButton btnStart;
    private javax.swing.JComboBox comboActivation;
    private javax.swing.JComboBox comboLearning;
    private javax.swing.JPanel groupExecution;
    private javax.swing.JPanel groupLearningParameters;
    private javax.swing.JPanel groupNetworkTopology;
    private javax.swing.JPanel groupPrediction;
    private javax.swing.JPanel groupTrainingParameters;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JLabel labelActivationFunction;
    private javax.swing.JLabel labelCurrentEpoch;
    private javax.swing.JLabel labelCurrentMSE;
    private javax.swing.JLabel labelCurrentStatus;
    private javax.swing.JLabel labelEpochs;
    private javax.swing.JLabel labelExecution;
    private javax.swing.JLabel labelHidden1;
    private javax.swing.JLabel labelHidden2;
    private javax.swing.JLabel labelHidden3;
    private javax.swing.JLabel labelInput;
    private javax.swing.JLabel labelLearningAlgorithm;
    private javax.swing.JLabel labelLearningParameters;
    private javax.swing.JLabel labelLearningRate;
    private javax.swing.JLabel labelMSE;
    private javax.swing.JLabel labelMomentum;
    private javax.swing.JLabel labelNetworkTopology;
    private javax.swing.JLabel labelOutput;
    private javax.swing.JLabel labelPrediction;
    private javax.swing.JLabel labelTrainingFile;
    private javax.swing.JLabel labelTrainingLog;
    private javax.swing.JLabel labelTrainingParameters;
    private javax.swing.JLabel labelValidationLog;
    private javax.swing.JSpinner spinnerEpochs;
    private javax.swing.JSpinner spinnerHidden1;
    private javax.swing.JSpinner spinnerHidden2;
    private javax.swing.JSpinner spinnerHidden3;
    private javax.swing.JSpinner spinnerInput;
    private javax.swing.JSpinner spinnerOutput;
    private javax.swing.JTextField txtLearningRate;
    private javax.swing.JTextField txtMSE;
    private javax.swing.JTextField txtMomentum;
    private javax.swing.JTextArea txtPrediction;
    private javax.swing.JTextField txtTrainingFile;
    private javax.swing.JTextField txtTrainingLogFile;
    private javax.swing.JTextField txtValidationLogFile;
    // End of variables declaration//GEN-END:variables
    
    
    /**
     * Loads the network's weights from a file
     *
     * @param file
     *            The file where the network's weights are stored in
     */
    public void loadWeights(String file) {
        Vector<Double> weights = new Vector<Double>();
        try {
            BufferedReader in = new BufferedReader(new FileReader(file));
            
            // Ignore version
            String str = in.readLine();
            
            // Parse neurons per layer
            str = in.readLine();
            StringTokenizer tokenizer_comments = new StringTokenizer(str,";");
            String line = tokenizer_comments.nextToken();
            StringTokenizer tokenizer_numbers = new StringTokenizer(line,", ");
            int number_input_neurons = Integer.parseInt(tokenizer_numbers.nextToken());
            Vector <Integer> number_hidden_neurons = new Vector <Integer> ();
            while(tokenizer_numbers.hasMoreTokens())
                number_hidden_neurons.add(Integer.parseInt(tokenizer_numbers.nextToken()));
            int number_output_neurons = Integer.parseInt(number_hidden_neurons.get(number_hidden_neurons.size()-1).toString());
            number_hidden_neurons.remove(number_hidden_neurons.size()-1);
            
            // Parse activation functions
            IActivationFunction [] activations = new IActivationFunction[number_hidden_neurons.size()+2];
            str = in.readLine();
            tokenizer_comments = new StringTokenizer(str,";");
            line = tokenizer_comments.nextToken();
            tokenizer_numbers = new StringTokenizer(str,", ");
            for(int x = 0; x < number_hidden_neurons.size()+2; x++)
                if(Integer.parseInt(tokenizer_numbers.nextToken()) == 0)
                    activations[x] = new ActivationFunctionLinear();
                else
                    activations[x] = new ActivationFunctionSigmoid();
            
            // Parse weights
            str = in.readLine();
            while (str != null) {
                tokenizer_comments = new StringTokenizer(str,";");
                line = tokenizer_comments.nextToken();
                weights.add(Double.parseDouble(line));
                str = in.readLine();
            }
            
            // Build network
            this.spinnerInput.setValue(new Integer(number_input_neurons));
            this.spinnerOutput.setValue(new Integer(number_output_neurons));
            if(number_hidden_neurons.size() > 0)
                this.spinnerHidden1.setValue(Integer.parseInt(number_hidden_neurons.get(0).toString()));
            if(number_hidden_neurons.size() > 1)
                this.spinnerHidden2.setValue(Integer.parseInt(number_hidden_neurons.get(1).toString()));
            if(number_hidden_neurons.size() > 2)
                this.spinnerHidden3.setValue(Integer.parseInt(number_hidden_neurons.get(2).toString()));
            
            int [] hidden_neurons = new int[number_hidden_neurons.size()];
            for(int x = 0; x < number_hidden_neurons.size(); x++)
                hidden_neurons[x] = number_hidden_neurons.get(x);
            network = new FeedForwardNeuralNetwork(number_input_neurons,hidden_neurons,number_output_neurons);
            
            for(int x = 0; x < network.neuron_layers.size(); x++)
                network.neuron_layers.get(x).setActivationFunction(activations[x]);
            
            network.setWeightVector(weights);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    /**
     * Saves the network's weights to a file
     *
     * @param file
     *            The file where the network's weights are going to be stored in
     */
    public void saveWeights(String file) {
        try {
            PrintWriter out = new PrintWriter(new FileOutputStream(file));
            
            // Print version
            out.println("1; Version of this file save/restore protocol for BPNs");
            
            for(int x = 0; x < this.network.neuron_layers.size(); x++) {
                out.print(this.network.neuron_layers.get(x).getNumberNeurons(Neuron.NeuronType.Normal));
                if(x < this.network.neuron_layers.size() -1)
                    out.print(", ");
            }
            out.println("; Layer sizes of BPN.");
            
            // Print the transfer functions
            out.print("0, ");
            for(int x = 0; x < this.network.neuron_layers.size() - 2; x++)
                out.print(activation != 0 ? "0, " : "1, ");
            out.print(activation != 0 ? "0" : "1");
            out.println(" ; Transfer functions of BPN (0 for non linear, 1 for sigmoid )");
            
            int input_neurons = this.network.neuron_layers.get(0).getNumberNeurons(Neuron.NeuronType.Normal);
            int [] hidden_neurons = new int[this.network.neuron_layers.size()-2];
            int output_neurons = this.network.neuron_layers.get(this.network.neuron_layers.size()-1).getNumberNeurons(Neuron.NeuronType.Normal);
            for(int x = 0; x < hidden_neurons.length; x++)
                hidden_neurons[x] = this.network.neuron_layers.get(x+1).getNumberNeurons(Neuron.NeuronType.Normal);
            
            // Print the weights
            int neuron_i = 1;
            int neuron_j = 1;
            int layer = 1;
            boolean input = true;
            boolean hid = false;
            boolean output = false;
            Vector <Double> weights = this.network.getWeightVector();
            for (Double value : weights) {
                if(input) {
                    out.println(value + "; " + neuron_i + " " + neuron_j + " " + layer);
                    neuron_i++;
                    if(neuron_i > input_neurons + FeedForwardNeuralNetwork.DEFAULT_NUMBER_BIAS_NEURONS) {
                        neuron_i = 1;
                        neuron_j++;
                        if(neuron_j > hidden_neurons[layer-1]) {
                            neuron_j = 1;
                            layer++;
                            input = false;
                            if(hidden_neurons.length == 1)
                                output = true;
                            else
                                hid = true;
                        }
                    }
                } else
                    if(hid) {
                    out.println(value + "; " + neuron_i + " " + neuron_j + " " + layer);
                    neuron_i++;
                    if(neuron_i > hidden_neurons[layer-2] + FeedForwardNeuralNetwork.DEFAULT_NUMBER_BIAS_NEURONS) {
                        neuron_i = 1;
                        neuron_j++;
                        if(neuron_j > hidden_neurons[layer-1]) {
                            neuron_j = 1;
                            layer++;
                            if(layer > hidden_neurons.length) {
                                input = false;
                                hid = false;
                                output = true;
                            }
                        }
                    }
                    } else
                        if(output) {
                    out.println(value + "; " + neuron_i + " " + neuron_j + " " + layer);
                    neuron_i++;
                    if(neuron_i > hidden_neurons[layer-2] + FeedForwardNeuralNetwork.DEFAULT_NUMBER_BIAS_NEURONS) {
                        neuron_i = 1;
                        neuron_j++;
                        if(neuron_j > output_neurons) {
                            input = false;
                            hid = false;
                            output = false;
                        }
                    }
                        }
            }
            
            out.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}
